#pragma noce

#include <iostream>
#include <string>
#include <algorithm>
#include <assert.h>
#include "Iterator.h"

namespace zfox
{
    template <typename T>
    class vector
    {
    public:
        typedef T *iterator;
        typedef const T *const_iterator;

        typedef ReverseIterator<iterator, T&, T*>  reverse_iterator;
        typedef ReverseIterator<const_iterator, const T&, const T*>  const_reverse_iterator;

        const_iterator begin() const
		{
			return _start;
		}

		const_iterator end() const
		{
			return _finsh;
		}

        iterator begin()
        {
            return _start;
        }

        iterator end()
        {
            return _finsh;
        }

        // 对称
		reverse_iterator rbegin()
		{
			return reverse_iterator(end());
		}

		reverse_iterator rend()
		{
			return reverse_iterator(begin());
		}

		const_reverse_iterator rbegin() const
		{
			return const_reverse_iterator(end());
		}

		const_reverse_iterator rend() const
		{
			return const_reverse_iterator(begin());
		}

        vector()
        {
            _finsh = nullptr;
            _start = nullptr;
            _end_of_storage = nullptr;
        }

        vector(const int n, const T &val = T())
        {
            reserve(n);
            for (int i = 0; i < n; i++)
                push_back(val);
        }

        vector(initializer_list<T> il)
        {
            reserve(il.size());
            for (auto e : il)
            {
                push_back(e);
            }
        }

        // 支持任意类型的迭代器初始化
        template <typename InputIterator>
        vector(InputIterator first, InputIterator last)
        {
            while (first != last)
            {
                push_back(*first);
                first++;
            }
        }

        vector(const vector<T> &v)
        {
            reserve(v.capacity());
            for (auto e : v)
            {
                push_back(e);
            }
        }

        void swap(vector<T> &v)
        {
            std::swap(_start, v._start);
            std::swap(_finsh, v._finsh);
            std::swap(_end_of_storage, v._end_of_storage);
        }

        // 这里从外面拷贝构造回来的局部变量 然后和局部变量交换空间 然后局部变量就把就空间析构掉了
        vector<T> &operator=(vector<T> v)
        {
            swap(v);
            return *this;
        }

        void reserve(size_t n)
        {
            if (n > capacity())
            {
                size_t oldsize = size();
                T *tmp = new T[n];
                if (_start)
                {
                    for (int i = 0; i < oldsize; i++) tmp[i] = _start[i];
                    delete[] _start;
                }

                _start = tmp;
                _finsh = _start + oldsize;
                _end_of_storage = _start + n;
            }
        }

        size_t size() const  { return _finsh - _start; }

        size_t capacity() const { return _end_of_storage - _start; }

        bool empty() const { return _start == _finish; }

        void push_back(const T &val) { insert(end(), val); }

        void pop_back()
        {
            assert(size() > 0);

            _finsh--;
        }

        T &operator[](size_t pos)
        {
            assert(pos < size());

            return _start[pos];
        }

        const T &operator[](size_t pos) const
        {
            assert(pos < size());

            return _start[pos];
        }

        iterator insert(iterator pos, const T &val)
        {
            assert(pos >= _start);
            assert(pos <= _finsh);

            if (_finsh == _end_of_storage)
            {
                size_t len = pos - _start;

                size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2;
                reserve(newcapacity);

                pos = _start + len;
            }

            iterator end = _finsh - 1;
            while (end >= pos)
            {
                *(end + 1) = *end;
                --end;
            }
            *pos = val;

            _finsh++;
            return pos;
        }

        // 迭代器失效问题
        iterator erase(iterator pos)
        {
            assert(pos >= _start);
            assert(pos < _finsh);

            iterator it = pos + 1;
            while (it != _finsh)
            {
                *(it - 1) = *it;
                ++it;
            }

            --_finsh;
            return pos;
        }

        ~vector()
        {
            if (_start)
            {
                delete[] _start;
                _start = _finsh = _end_of_storage = nullptr;
            }
        }

    private:
        T *_start = nullptr;
        T *_finsh = nullptr; // 最后一个元素的下一个位置
        T *_end_of_storage = nullptr;
    };
}